package com.example.eureka_client.service.impl;

import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.example.eureka_client.entity.AttentionQuestion;
import com.example.eureka_client.entity.Question;
import com.example.eureka_client.entity.QuestionAgree;
import com.example.eureka_client.httpResult.ResultGenerator;
import com.example.eureka_client.mapper.AttentionQuestionMapper;
import com.example.eureka_client.mapper.QuestionAgreeMapper;
import com.example.eureka_client.mapper.QuestionMapper;
import com.example.eureka_client.service.IQuestionService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.example.eureka_client.utils.PageRequest;
import com.example.eureka_client.utils.PageResult;
import com.example.eureka_client.utils.PageUtils;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageInfo;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;

/**
 * <p>
 * 问题表 服务实现类
 * </p>
 *
 * @author plj
 * @since 2022-03-24
 */
@Service
public class QuestionServiceImpl extends ServiceImpl<QuestionMapper, Question> implements IQuestionService {
    @Resource
    QuestionAgreeMapper questionAgreeMapper;
    @Resource
    AttentionQuestionMapper attentionQuestionMapper;

    private final static SimpleDateFormat sdf= new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");

    @Override
    public Question getById(String id){
        return baseMapper.getById(id);
    }

    @Override
    public boolean delById(String id){
        return baseMapper.delById(id);
    }

    @Override
    public PageResult getAllQuestionByUserId(String userId, PageRequest pageRequest){
        List<Question> questions = baseMapper.getAllQuestionsByUserId(userId);
        int pageNum = pageRequest.getPageNum();
        int pageSize = pageRequest.getPageSize();
        Page page = new Page(pageNum, pageSize);
        int total = questions.size();
        page.setTotal(total);
        int startIndex = (pageNum - 1) * pageSize;
        int endIndex = Math.min(startIndex + pageSize, total);

        if (startIndex > endIndex) {
            page.addAll(new ArrayList());
            PageInfo pageInfo = new PageInfo<>(page);
            return PageUtils.getPageResult(pageRequest,pageInfo);
        } else {
            page.addAll(questions.subList(startIndex, endIndex));
            PageInfo pageInfo = new PageInfo<>(page);
            return PageUtils.getPageResult(pageRequest,pageInfo);
        }
    }

    @Override
    public PageResult sortByWatchUserNum(PageRequest pageRequest){
        List<Question> results = this.list();

        results.sort(Comparator.comparing(Question::getWatchUserNum).reversed());

        int pageNum = pageRequest.getPageNum(), pageSize = pageRequest.getPageSize();
        Page page = new Page(pageNum, pageSize);

        int total = results.size();
        page.setTotal(total);
        int startIndex = (pageNum - 1) * pageSize;
        int endIndex = Math.min(startIndex + pageSize, total);

        if (startIndex > endIndex) {
            page.addAll(new ArrayList());
            PageInfo pageInfo = new PageInfo<>(page);
            return PageUtils.getPageResult(pageRequest,pageInfo);
        } else {
            page.addAll(results.subList(startIndex, endIndex));
            PageInfo pageInfo = new PageInfo<>(page);
            return PageUtils.getPageResult(pageRequest,pageInfo);
        }
    }

    @Override
    public PageResult sortByTime(PageRequest pageRequest){
        List<Question> results = this.list();

        // results.sort(Comparator.comparing(Question::getWatchUserNum).reversed());
        // 根据时间降序
        results.sort(Comparator.comparing(Question::getCreateTime,(x,y)->{
            try {
                Date new_x = sdf.parse(x), new_y = sdf.parse(y);
                if(new_x.after(new_y)) return -1;
                else if(new_x.equals(new_y)) return 0;
                else return 1;
            } catch (ParseException e) {
                e.printStackTrace();
                return 0;
            }
        }));

        int pageNum = pageRequest.getPageNum(), pageSize = pageRequest.getPageSize();
        Page page = new Page(pageNum, pageSize);

        int total = results.size();
        page.setTotal(total);
        int startIndex = (pageNum - 1) * pageSize;
        int endIndex = Math.min(startIndex + pageSize, total);

        if (startIndex > endIndex) {
            page.addAll(new ArrayList());
            PageInfo pageInfo = new PageInfo<>(page);
            return PageUtils.getPageResult(pageRequest,pageInfo);
        } else {
            page.addAll(results.subList(startIndex, endIndex));
            PageInfo pageInfo = new PageInfo<>(page);
            return PageUtils.getPageResult(pageRequest,pageInfo);
        }
    }

    @Override
    public PageResult sortRandom(PageRequest pageRequest){
        List<Question> results = this.list();

        //results.sort(Comparator.comparing(Question::getWatchUserNum).reversed());
        Collections.shuffle(results);

        int pageNum = pageRequest.getPageNum(), pageSize = pageRequest.getPageSize();
        Page page = new Page(pageNum, pageSize);

        int total = results.size();
        page.setTotal(total);
        int startIndex = (pageNum - 1) * pageSize;
        int endIndex = Math.min(startIndex + pageSize, total);

        if (startIndex > endIndex) {
            page.addAll(new ArrayList());
            PageInfo pageInfo = new PageInfo<>(page);
            return PageUtils.getPageResult(pageRequest,pageInfo);
        } else {
            page.addAll(results.subList(startIndex, endIndex));
            PageInfo pageInfo = new PageInfo<>(page);
            return PageUtils.getPageResult(pageRequest,pageInfo);
        }
    }

    @Override
    public PageResult getAttentionQuestion(List<String> questionIds, PageRequest pageRequest){
        List<Question> questions = baseMapper.getAllQuestionsByQuestionIds(questionIds);

        int pageNum = pageRequest.getPageNum(), pageSize = pageRequest.getPageSize();
        Page page = new Page(pageNum, pageSize);

        int total = questions.size();
        page.setTotal(total);
        int startIndex = (pageNum - 1) * pageSize;
        int endIndex = Math.min(startIndex + pageSize, total);

        if (startIndex > endIndex) {
            page.addAll(new ArrayList());
            PageInfo pageInfo = new PageInfo<>(page);
            return PageUtils.getPageResult(pageRequest,pageInfo);
        } else {
            page.addAll(questions.subList(startIndex, endIndex));
            PageInfo pageInfo = new PageInfo<>(page);
            return PageUtils.getPageResult(pageRequest,pageInfo);
        }
    }


    @Override
    public boolean editQuestion(String questionId, String title, String content){
        Date time = new Date();

        UpdateWrapper<Question> updateWrapper = new UpdateWrapper<>();
        updateWrapper.eq("ID", questionId);
        updateWrapper.set("UPDATE_TIME", sdf.format(time));

        if(!title.equals("")) updateWrapper.set("TITLE", title);
        if(!content.equals("")) updateWrapper.set("CONTENT", content);
        if(this.update(null, updateWrapper)) return true;
        else return false;
    }

    @Override
    public boolean addWatchNum(String questionId){
        Date time = new Date();
        Question question = this.getById(questionId);

        UpdateWrapper<Question> updateWrapper = new UpdateWrapper<>();
        updateWrapper.eq("ID", questionId);

        updateWrapper.set("WATCH_USER_NUM", question.getWatchUserNum() + 1);

        if(this.update(null, updateWrapper)) return true;
        else return false;
    }

    @Override
    public boolean addAgreeNum(String questionId, String userId){
        Question question = this.getById(questionId);

        UpdateWrapper<Question> updateWrapper = new UpdateWrapper<>();
        updateWrapper.eq("ID", questionId);

        updateWrapper.set("AGREE_NUM", question.getAgreeNum() + 1);

        QuestionAgree questionAgree = new QuestionAgree();
        questionAgree.setQuestionId(questionId);
        questionAgree.setUserId(userId);

        if(questionAgreeMapper.insert(questionAgree) == 1 && this.update(null, updateWrapper)) return true;
        else return false;
    }

    @Override
    public boolean addAttentionNum(AttentionQuestion attentionQuestion){
        Question question = this.getById(attentionQuestion.getQuestionId());

        UpdateWrapper<Question> updateWrapper = new UpdateWrapper<>();
        updateWrapper.eq("ID", attentionQuestion.getQuestionId());

        updateWrapper.set("ATTENTION_NUM", question.getAttentionNum() + 1);

        if(attentionQuestionMapper.insert(attentionQuestion) == 1 && this.update(null, updateWrapper)) return true;
        else return false;
    }

    @Override
    public boolean reAgreeNum(String questionId, String UserId){
        Question question = this.getById(questionId);

        UpdateWrapper<Question> updateWrapper = new UpdateWrapper<>();
        updateWrapper.eq("ID", questionId);

        updateWrapper.set("AGREE_NUM", question.getAgreeNum() - 1);

        QuestionAgree questionAgree = new QuestionAgree();
        questionAgree.setQuestionId(questionId);
        questionAgree.setUserId(UserId);

        if(questionAgreeMapper.deleteById(questionAgree.getQuestionId(), questionAgree.getUserId()) && this.update(null, updateWrapper)) return true;
        else return false;
    }

    @Override
    public boolean reAttentionNum(AttentionQuestion attentionQuestion){
        Question question = this.getById(attentionQuestion.getQuestionId());

        UpdateWrapper<Question> updateWrapper = new UpdateWrapper<>();
        updateWrapper.eq("ID", attentionQuestion.getQuestionId());

        updateWrapper.set("ATTENTION_NUM", question.getAttentionNum() - 1);

        if(attentionQuestionMapper.deleteById(attentionQuestion.getUserId(), attentionQuestion.getQuestionId()) && this.update(null, updateWrapper)) return true;
        else return false;
    }

    @Override
    public boolean agree(String questionId, String userId){
        QuestionAgree questionAgree = questionAgreeMapper.getBy(userId, questionId);
        if(questionAgree != null) return true;
        else return false;
    }

    @Override
    public boolean attention(String questionId, String UserId){
        AttentionQuestion attentionQuestion = attentionQuestionMapper.getByTwo(UserId, questionId);
        if(attentionQuestion != null) return true;
        else return false;
    }
}
